/*
 * @Author: guoyangf
 * @Date: 2020-06-03 15:03:03
 * @LastEditTime: 2020-08-28 16:19:04
 * @Description: file content
 */
import { Component } from 'react';
import { base, toast, timeFunctionTranslater } from 'nc-lightapp-front';
import SearchTableStatusCtrl from '../search_table_status_ctrl/SearchTableStatusCtrl';
import classnames from 'classnames';
import { requestPromise } from 'src/erm/sscrppublic/common/utils/asyncFunctions.js';
import { setSearch } from '../../../../utils/setComponentUsed'
import './index.less';

const { NCSelect, NCFormControl, NCCheckbox, NCDiv, NCRangePickerClient } = base;
const NCOption = NCSelect.NCOption;

class SearchCtrl extends Component {

    constructor(props) {
        super(props);
        this.NCProps = window.__SSC_NCProps;
        setSearch(this.NCProps, props.searchTplArea);

        this.state = {
            multiLang: {},
            tileJSXArr: [],
            foldJSXArr: [],
            isFold: false,
            specialSearchData: {}, //存放平铺的数据
            timeRangeData: {}, //存放平铺字段需要展示时间区域的数据
            customSearchData: {}, //存放自定义数据
            barCodeValue: null, //扫描
            fuzzyquerychild: []
        }
        this.fuzzyQueryKey = [];

        this.multiLangPromise = window.__SSC_MultiLangPromise;
        if (this.multiLangPromise) {
            this.multiLangPromise.then((multiLang) => {
                this.setState({
                    multiLang
                })
            })
        }

    }


    setIsFold = () => {
        this.setState({
            isFold: !this.state.isFold
        }, () => {
            this.NCProps.table.updateTableHeight();
        })
    }

    dataToJSX = (multiLang) => {
        let customField = this.props.customField;
        let meta = this.NCProps.meta.getMeta() || {};
        let searchTpl = meta[this.props.searchTplArea];
        let specialDisplayCondition = this.props.specialDisplayCondition || {};

        /**
         * 处理平铺和自定义字段的ui
         * @param {*} data 
         */
        let execFn = (data = []) => {
            let tileJSXArr = [];
            let foldJSXArr = [];
            let specialSearchData = this.state.specialSearchData;
            data.forEach((item) => {
                let attrcode = item.attrcode;
                let customFieldEvent = this.props.customFieldEvent || {};
                let fieldEvent = customFieldEvent[item.attrcode];
                if (!specialSearchData[attrcode] && !this.state.timeRangeData[attrcode] && item.initialvalue) {
                    specialSearchData[attrcode] = { value: item.initialvalue.value, display: item.initialvalue.display };

                }
                let specialValue = specialSearchData[attrcode] && specialSearchData[attrcode].value;
                let tileJSX, foldJSX;
                switch (item.itemtype) {
                    case 'multi-lv': //多层级查询布局类型，如更多条件
                        let subJSX = execFn(item.children);
                        tileJSX = (
                            <div className="filter-wrap" style={{ width: '100%' }}>
                                <span className="label">{item.label}：</span>
                                {subJSX.tileJSXArr}
                            </div>
                        );
                        foldJSX = (
                            <div className="filter-wrap" style={{ width: '100%', paddingTop: '5px' }}>
                                <span className="label">{item.label}：</span>
                                {subJSX.foldJSXArr}
                            </div>
                        )
                        break;
                    case 'checkbox':
                        tileJSX = foldJSX = (
                            <div className="custom-condition">
                                <NCCheckbox
                                    onChange={(val) => {
                                        this.setState({
                                            [item.attrcode]: val
                                        })
                                        fieldEvent && fieldEvent(val);
                                    }}
                                    checked={this.state[item.attrcode]}
                                >
                                    {item.label}
                                </NCCheckbox>
                            </div>
                        );
                        break;
                    case 'barcode':
                        tileJSX = foldJSX = (
                            <div className="custom-condition" style={{ width: '226px' }}>
                                <NCFormControl
                                    fieldid="barcode-query"
                                    value={this.state.barCodeValue}
                                    placeholder={item.placeholder}
                                    onChange={(val) => {
                                        if (val === '') { //清空时查询
                                            if (!fieldEvent || !fieldEvent.notClearInvokeQuery) { //我的打印清空时，不调用查询
                                                this.props.searchEvent && this.props.searchEvent(this.getQueryCondition());
                                            }
                                        }
                                        this.setState({
                                            barCodeValue: val
                                        })
                                        //fieldEvent && fieldEvent.onChange && fieldEvent.onChange();
                                    }}
                                    type='search'
                                    onSearch={() => {
                                        fieldEvent && fieldEvent.onSearch && fieldEvent.onSearch(this.state.barCodeValue);
                                    }}
                                />
                            </div>
                        );
                        break;
                    case 'fuzzySearch':

                        let timer = null;
                        tileJSX = foldJSX = (
                            <div className="custom-condition">
                                <NCSelect
                                    fieldid="fuzzy-query"
                                    className="fuzzyquery"
                                    height="24px"
                                    tags
                                    supportSearch={true}
                                    searchPlaceholder={multiLang['job-common-search-bqms']/*标签模式*/}
                                    placeholder={multiLang['job-common-search-mhcx']/*模糊查询*/}
                                    data={this.state.fuzzyquerychild}
                                    onSearch={(val) => {

                                        clearTimeout(timer);
                                        timer = setTimeout(async () => {
                                            let newQueryParam = JSON.parse(JSON.stringify(fieldEvent.queryParam));
                                            newQueryParam.fuzzyQueryKey = val
                                            try {
                                                //获取驳回初始化信息
                                                const result = await requestPromise({
                                                    url: fieldEvent.url || '/nccloud/ssctp/sscbd/SSCTaskBlurQueryAction.do',
                                                    data: newQueryParam
                                                });

                                                let fuzzyquerychild = this.state.fuzzyquerychild;

                                                result.data.forEach((item) => {
                                                    let obj = {};
                                                    obj.value = item.value + '=' + val;
                                                    obj.key = item.key + multiLang['job-common-search-bh'] + val;//包含 
                                                    fuzzyquerychild.push(obj);
                                                })
                                                this.setState({ fuzzyquerychild });

                                            } catch (e) {
                                                toast({ title: e.message, duration: 5, color: 'danger', })
                                            }
                                        }, 500)
                                    }}
                                    value={this.state.fuzzyQueryValue}
                                    onChange={(data) => {
                                        this.setState({
                                            fuzzyQueryValue: data
                                        });

                                        let fuzzyquerychild = [];
                                        if (data) { //data为空时是清空操作， 需要清空记录。 不为控制进行下面的逻辑
                                            this.state.fuzzyquerychild.forEach((item) => { //取消没有选择的项
                                                if (data.includes(item.value)) {
                                                    fuzzyquerychild.push(item);
                                                }
                                            })
                                        }
                                        this.setState({ fuzzyquerychild })

                                        this.fuzzyQueryKey = data || [];
                                        this.props.searchEvent && this.props.searchEvent(this.getQueryCondition())
                                    }}
                                >
                                </NCSelect>
                            </div>

                        );

                        break;
                    case 'select':
                    default:
                        //let width = specialDisplayCondition[item.attrcode]
                        let rangeDatePicker = null;
                        if (item.isShowRangeDatePicker) {
                            rangeDatePicker = (
                                <NCRangePickerClient
                                    showTimeFunction={true}
                                    onChange={v => {
                                        let timeRangeData = this.state.timeRangeData;
                                        let preVal = timeRangeData[item.attrcode] && timeRangeData[item.attrcode].rawVal;
                                        //组件bug，默认会执行两次，判断是否选取重复值。 
                                        if (preVal && v && v.length == preVal.length && v[0] == preVal[0] && v[1] == preVal[1]) {
                                            return;
                                        }
                                        if (!v) {
                                            delete timeRangeData[item.attrcode];
                                        } else {
                                            timeRangeData[item.attrcode] = {
                                                rawVal: v,
                                                formatVal: {
                                                    firstvalue: timeFunctionTranslater(v[0], null),
                                                    secondvalue: timeFunctionTranslater(v[1], { flag: false })
                                                }
                                            }
                                        }

                                        
                                        delete specialSearchData[item.attrcode];
                                        this.setState({
                                            timeRangeData,
                                            specialSearchData
                                        }, () => {
                                            this.props.searchEvent && this.props.searchEvent(this.getQueryCondition())
                                        })

                                    }}
                                    value={this.state.timeRangeData[item.attrcode] && this.state.timeRangeData[item.attrcode].rawVal || ""}
                                    className="SSCTimeRangePicker"
                                ></NCRangePickerClient>
                            )
                        }
                        item.options || (item.options = []);
                        tileJSX = (
                            <div className="filter-wrap" style={{ width: item.width }}>
                                <span className="label">{item.label}：</span>
                                <span className="values-wrap">
                                    {item.options.map((option) => {
                                        let count = item.isShowNum && option.num; //如单据类型有数量提示
                                        return (
                                            <span 
                                                className={classnames('value nc-theme-common-font-c', {'active nc-theme-activ-font-c nc-theme-activ-area-bgc': specialValue == option.value})}
                                                onClick={e => this.tileFieldOnClick(item.attrcode, option)}
                                            >
                                                {option.display}
                                                {count && <span>{count}</span>}
                                            </span>
                                        )
                                    })}
                                </span>
                                <span>
                                    {rangeDatePicker}
                                </span>
                            </div>
                        );
                        foldJSX = (
                            <div className='filter-wrap' style={{ display: 'none' }}>
                                <span className='label'>
                                    {item.label}：
                                </span>
                                <NCSelect
                                    fieldid={item.attrcode}
                                    className='select-filter'
                                    value={specialValue}
                                    onChange={
                                        (value) => {
                                            this.tileFieldOnClick(item.attrcode, item.options.find(option => option.value == value))
                                        }
                                    }
                                    showClear={false}
                                >
                                    {item.options.map((option) => {
                                        return <NCOption value={option.value}>{option.display}</NCOption>

                                    })}
                                </NCSelect>
                            </div>
                        );
                }
                tileJSXArr.push(tileJSX);
                foldJSXArr.push(foldJSX);
            });
            return {
                tileJSXArr,
                foldJSXArr
            }
        }

        let specialFieldArr = [];
        this.specialAndCustomFieldArr = [];

        //特殊字段处理
        if (searchTpl) {
            searchTpl.items.forEach((item) => {

                //字段值根据queryData返回的结果确定
                if (this.props.extendableSearchFieldValueObj[item.attrcode]) {
                    let label = item.label;
                    item = this.props.extendableSearchFieldValueObj[item.attrcode];
                    item.label = label; //使用模板配置的label
                }

                let config = specialDisplayCondition[item.attrcode];
                if (config) {
                    let width = '100%';
                    config.colums == 1 && (width = '50%');
                    item.isShowRangeDatePicker = config.isShowRangeDatePicker
                    item.width = width;
                    item.isShowNum = config.isShowNum;
                    specialFieldArr.push(item)
                }
                //硬编码timerange字段都要显示日期区间选择器
                if (item.attrcode == 'timerange') {
                    item.isShowRangeDatePicker = true;
                }
            })
        }

        //合并特殊字段和自定义字段
        if (customField) { //前台硬编码的自定义字段：如更多条件
            this.specialAndCustomFieldArr = specialFieldArr.concat(customField);
        }

        return execFn(this.specialAndCustomFieldArr);
    }

    /**
     * 平铺字段点击事件
     */
    tileFieldOnClick = (code, option) => {
        let specialSearchData = this.state.specialSearchData;
        specialSearchData[code] = { ...option }; //这里重新创建对象，否则reset方法中复制导致对象引用错乱

        let timeRangeData = this.state.timeRangeData;
        delete timeRangeData[code];

        this.setState({
            specialSearchData,
            timeRangeData
        })
        this.props.searchEvent && this.props.searchEvent(this.getQueryCondition())
    }

    /**
     *获取查询条件
     *
     * @returns
     * @memberof SearchCtrl
     */
    getQueryCondition() {
        let querycondition = this.NCProps.search.getAllSearchData(this.props.searchTplArea);

        if (!querycondition) { //这里需要做数据兼容。因为当查询模板被清空时，可能querycondition为false，导致后续不能组装平铺的特殊字段。
            querycondition = { conditions: [], logic: 'and' }
        }

        let meta = this.NCProps.meta.getMeta() || {};
        let searchTpl = meta[this.props.searchTplArea];
        let oid = searchTpl.oid;
        let searchTplItems = searchTpl.items;
        let specialSearchData = this.state.specialSearchData;
        let timeRangeData = this.state.timeRangeData;
        searchTplItems.forEach((item) => {
            let attrcode = item.attrcode;
            let option = specialSearchData[attrcode];
            if (option) {
                //拼接成查询组件的提交时规定的格式
                let specialFieldCondition = {
                    datatype: item.datatype,
                    display: option.display,
                    field: attrcode,
                    isIncludeSub: false,
                    oprtype: "=",
                    refurl: "",
                    timeFunction: "",
                    value: { firstvalue: option.value, secondvalue: "" }
                }
                querycondition.conditions.push(specialFieldCondition);
            }

            let timeRange = timeRangeData[attrcode];
            if (timeRange) {
                //拼接成查询组件的提交时规定的格式
                let specialFieldCondition = {
                    datatype: item.datatype,
                    display: '',
                    field: attrcode,
                    isIncludeSub: false,
                    oprtype: "=",
                    refurl: "",
                    timeFunction: "",
                    value: timeRange.formatVal
                }
                querycondition.conditions.push(specialFieldCondition);
            }

        })

        //模糊查询字段。特别处理
        querycondition.conditions.push({
            datatype: '1',
            display: '',
            field: 'blur',
            isIncludeSub: false,
            oprtype: "=",
            refurl: "",
            timeFunction: "",
            value: { "firstvalue": this.fuzzyQueryKey.join(','), "secondvalue": "" }
        })

        return { oid, querycondition }; //queryCondition注意C大小写。后台接口参数全部小写
    }


    resetSearchAreaFiledAndQuery() {
        let specialSearchData = this.state.specialSearchData;
        this.specialAndCustomFieldArr.forEach((item) => {
            let specialItem = specialSearchData[item.attrcode];
            if (specialItem) {
                specialItem.display = item.initialvalue.display;
                specialItem.value = item.initialvalue.value;
            }
        })
        //1.先清空所有可见字段
        this.NCProps.search.clearSearchArea(this.props.searchTplArea); //清空查询模板
        let meta = this.NCProps.meta.getMeta() || {};
        let searchTpl = meta[this.props.searchTplArea];
        //2.再将可见字段中，有默认值的字段重置为默认值
        searchTpl.items.forEach((item) => {
            if (item.visible && item.initialvalue) {
                this.NCProps.search.setSearchValByField(this.props.searchTplArea, item.attrcode, { ...item.initialvalue });
            }
        })
        this.setState({
            specialSearchData
        }, () => {
            this.props.searchEvent && this.props.searchEvent(this.getQueryCondition())
        })
    }

    componentDidMount() {
        if (this.props.isShow) {
            this.props.searchEvent && this.props.searchEvent(this.getQueryCondition())
        }
    }

    componentDidUpdate(prevProps, prevState) {
        if (prevProps.isShow != this.props.isShow && this.props.isShow) {
            this.props.searchEvent && this.props.searchEvent(this.getQueryCondition())
        }
    }

    render() {
        const multiLang = this.props.comMultiLang || this.state.multiLang;
        const { search } = this.NCProps;
        let { NCCreateSearch } = search;
        let { tileJSXArr, foldJSXArr } = this.dataToJSX(multiLang);


        return (
            <NCDiv areaCode={NCDiv.config.SEARCH} className={classnames("search-ctrl-wrap", { "hide": !this.props.isShow })}>
                <div className="special-search-area nc-theme-gray-area-bgc nc-theme-area-split-bc">
                    <div className="tile-wrap" style={{ display: this.state.isFold ? 'none' : 'flex' }}>
                        {tileJSXArr}
                    </div>
                    <div className="fold-wrap" style={{ "display": this.state.isFold ? 'flex' : 'none' }}>
                        {foldJSXArr}
                    </div>
                </div>
                <div className={classnames("tpl-search-area nc-theme-gray-area-bgc nc-theme-area-split-bc", { "hide": !this.props.isShowAdvSearchArea || this.state.isFold })}>
                    <div className='label'>
                        {multiLang['job-common-gjcx']} {/* 高级查询： */}
                    </div>
                    <div style={{ flex: 1 }}>
                        {NCCreateSearch(this.props.searchTplArea, {
                            clickSearchBtn: (...params) => {
                                this.props.searchEvent && this.props.searchEvent(this.getQueryCondition())
                            },
                            defaultConditionsNum: 1,
                            showAdvBtn: false,
                            onAfterEvent: (...params) => {

                            }
                        })}
                    </div>

                </div>
                {/* 右下角搜索区折叠和缩略图切换按钮控制 */}
                <SearchTableStatusCtrl
                    iconBtnEvent={this.props.iconBtnEvent}
                    setIsFold={this.setIsFold}
                    comMultiLang={multiLang}
                />
            </NCDiv>
        )
    }
}



export default SearchCtrl;